package com.xiaoyu.lanling.feature.location

import `in`.srain.cube.util.CLog
import `in`.srain.cube.util.TimeUtils
import `in`.srain.cube.util.internal.AppConsumer
import com.amap.api.location.AMapLocation
import com.amap.api.location.AMapLocationClient
import com.amap.api.location.AMapLocationClientOption
import com.amap.api.location.AMapLocationListener
import com.xiaoyu.base.app.AppContext

class LocationHelper {

    private var mClient: AMapLocationClient?
    private var mLocationListener: AppConsumer<AMapLocation>? = null

    private var mDestroyOnceChanged = false

    private fun onSuccess(location: AMapLocation) {
        mLocationListener?.accept(location)
    }

    private fun onError() {
        mLocationListener?.accept(null)
    }

    fun getLocation(listener: AppConsumer<AMapLocation>) {
        setLocationListener(listener)
        setDestroyOnceChanged(true)
        start()
    }

    private val defaultOption: AMapLocationClientOption
        get() {
            val option = AMapLocationClientOption()
            option.locationMode = AMapLocationClientOption.AMapLocationMode.Hight_Accuracy
            option.isOnceLocation = true
            option.isMockEnable = false
            option.httpTimeOut = 8 * TimeUtils.MILLIS_IN_SECOND
            return option
        }

    fun setLocationListener(listener: AppConsumer<AMapLocation>) {
        mLocationListener = listener
    }

    fun start() {
        CLog.i(TAG, "location start")
        mClient?.startLocation()
    }

    fun stop() {
        CLog.i(TAG, "location stop")
        mClient?.stopLocation()
    }

    fun destroy() {
        CLog.i(TAG, "location destroy")
        mClient?.onDestroy()
        mClient = null
    }

    fun setDestroyOnceChanged(destroyOnceChanged: Boolean) {
        mDestroyOnceChanged = destroyOnceChanged
    }

    private inner class AMapLocationListenerImpl : AMapLocationListener {
        override fun onLocationChanged(location: AMapLocation) {
            if (mDestroyOnceChanged) {
                stop()
                destroy()
            }
            if (location.errorCode != 0) {
                onError()
                CLog.e(TAG, "location error, error code: %s, error info: %s", location.errorCode, location.errorInfo)
                return
            }
            CLog.i(TAG, "location success %s", location)
            onSuccess(location)
        }
    }

    companion object {
        private val TAG = LocationHelper::class.java.name
    }

    init {
        mClient = AMapLocationClient(AppContext.getContext())
        mClient?.setLocationOption(defaultOption)
        mClient?.setLocationListener(AMapLocationListenerImpl())
    }
}